package test

import (
	"bytes"
	"fmt"
	"google.golang.org/protobuf/proto"
	"log"
	"net"
	"reflect"
	"src/connection"
	"src/model"
	"src/model/ProtoModel"
	"strconv"
	"time"
)

// 发消息
func sendMessage(i int) []byte {
	var idx int64 = int64(i)
	msgm := ProtoModel.MessageProto{Id: idx}
	msgm.Receiver = "1074"
	msgm.SendTime = time.Now().Unix()
	msgm.Content = map[string]string{"abc": "bcd"}
	//msg := ProtoModel.MessagesPubProto{}
	//msg.Msg = append(msg.Msg, &msgm)
	//msg.Sid = "beijing1"
	//msg.Uid = "1076"
	marshal, err := proto.Marshal(&msgm)
	if err != nil {
		return nil
	}
	buf := bytes.Buffer{}
	//buf.WriteByte(byte(ProtoModel.SendActProto_SENDALL.Number()))
	buf.WriteByte(byte(ProtoModel.DataTypeProto_MESSAGE.Number()))
	buf.Write(marshal)
	return buf.Bytes()
}

// 结构体转 map
func StructToMap(obj interface{}) map[string]string {
	t := reflect.TypeOf(obj)
	v := reflect.ValueOf(obj)
	var data = make(map[string]string)
	for i := 0; i < t.NumField(); i++ {
		data[t.Field(i).Name] = v.Field(i).String()
	}
	return data
}

// 请求结构图数据包
func sendBody(i int) []byte {
	var idx2 string = strconv.Itoa(i)
	msgm := &ProtoModel.SendBodyProto{}
	msgm.Key = "client_bind"
	client := model.ClientBindProto{}
	client.Token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVaWQiOjE2LCJTY29wZSI6ODg4OCwiVU5hbWUiOiJhZG1pbjEwIiwiZXhwIjoxNjk1ODYxOTY2LCJpc3MiOiJqZXJyeSIsIlRva2VuIjoiIn0.2LZwErvEmuMx7UrobT6fJimM-Nx2vDMu0dAXDI7Nob8"
	client.DeviceId = ""
	client.Language = ""
	client.DeviceName = ""
	client.OsVersion = ""
	client.AppVersion = ""
	client.Channel = idx2
	client.PackageName = ""

	clidata := StructToMap(client)
	msgm.Data = clidata
	msgm.Timestamp = time.Now().Unix()
	//msg := ProtoModel.MessagesPubProto{}
	//msg.Msg = append(msg.Msg, &msgm)
	//msg.Sid = "beijing1"
	//msg.Uid = "1076"
	marshal, err := proto.Marshal(msgm)
	if err != nil {
		return nil
	}
	buf := bytes.Buffer{}
	//buf.WriteByte(byte(ProtoModel.SendActProto_SENDALL.Number()))
	buf.WriteByte(byte(ProtoModel.DataTypeProto_SENT.Number()))
	buf.Write(marshal)
	//send(buf.Bytes(), ipaddr)
	return buf.Bytes()
}
func main() {
	var ip = "127.0.0.1"
	var port = 9101
	var addr = ip + ":" + strconv.Itoa(port)
	//启动服务端
	//go createServer(ip, port)

	time.Sleep(1 * time.Second)

	byts2 := sendMessage(1)
	//go func() {
	// 1. 建立客户端
	client := getClient(addr)
	conn, _ := (&connection.Tcp{}).GetConn(client)
	conn.WriteMes(sendBody(1))
	go onMessage(conn)
	//每秒发一条消息
	//go func() {
	for {
		err := conn.WriteMes(byts2)
		if err != nil {
			log.Println(err)
		}
		time.Sleep(5 * time.Second)
	}
	time.Sleep(2 * time.Second)
	select {}
	//}

}

var idx int

func getClient(addr string) *net.Conn {
	// 1. 建立访问通道
	client, err := net.Dial("tcp", addr)
	if err != nil {
		panic(err)
	}
	return &client
}

// 客户端发消息
func clientSend(msg []byte, conn net.Conn) {
	_, err := (conn).Write(msg)
	if err != nil {
		return
	}
}

// 客户端 监听消息 和服务端逻辑差不多一样的
func onMessage(conn *connection.Tcp) {

	for {
		msg, err := conn.ReadMess()
		if err != nil {
			continue
		}
		//cmd, act, msgs, err := utils.MessageF.UnpackMessage(msg)
		byf := bytes.NewBuffer(msg)
		act, _ := byf.ReadByte()
		if ProtoModel.SendTypeProto(act) == ProtoModel.SendTypeProto_MESSAGE {
			data := ProtoModel.MessageProto{}
			proto.Unmarshal(byf.Bytes(), &data)
			fmt.Println("client send info to server si : ", act, data.String())
		}
	}
}

// 客户端 发消息 和服务端逻辑差不多一样的
func send(msg []byte, addr string) {
	// 1. 建立访问通道
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	//_, err = conn.Write([]byte(msg))

	_, err = conn.Write(msg)
	if err != nil {
		return
	}

}
